#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QInputDialog>
#include <QMessageBox>
#include <QTimer>
#include <QDebug>

// list of types of messages and protocol
#define MSG_TYPE_JOIN				1		// [user's name]
#define MSG_TYPE_LIST				2		// [peer's name]|[peer's name]|...|[peer's name]
#define MSG_TYPE_NOTICE				10		// [notice message]
#define MSG_TYPE_CHAT_NORMAL		11		// [chatter's name]|[chat message]
#define MSG_TYPE_CHAT_WHISPER_TO	12		// [target's name]|[chat message]
#define MSG_TYPE_CHAT_WHISPER_FROM	13		// [sender's name]|[chat message]

MainWindow::MainWindow(QWidget *parent) :
	QMainWindow(parent),
	ui(new Ui::MainWindow)
{
	// Initialize NGine
	NGLogger::info("Initializing NGine...");
	NGineClient::init("127.0.0.1", 5000, 0);
	NGLogger::info("NGine initialized!\n");

	bool ok, readyFlag = 0;
	while(!readyFlag)
	{
		username = QInputDialog::getText(this, "Enter your name to be displayed", "User name: ", QLineEdit::Normal, "", &ok);
		if(ok && !username.isEmpty())
		{
			// send MSG_TYPE_JOIN message to server
			NGineClient::sendToServer(MSG_TYPE_JOIN, username.toAscii());

			// this is needed because synchronous messaging is not yet implemented
			while(!readyFlag)
			{
				if(NGineClient::getQueueSize() > 0)
				{
					NGMessage *msg = NGineClient::getFirstMessage();
					if(msg->getType() == MSG_TYPE_JOIN)
					{
						if(!strcmp(msg->getData(), "SUCCESS"))
							readyFlag = 1;
						else
						{
							QMessageBox::information(this, "Error", "Username entered is already in use. Please enter a different name", QMessageBox::Ok);
							break;
						}
					}
				}
			}
		}
		else
		{
			// set a timer to kill the application when cancelled
			QTimer::singleShot(0, this, SLOT(close()));
			break;
		}
	}

	ui->setupUi(this);
	ui->lineEdit->setFocus();

	// connect UI components
	connect(ui->sendButton, SIGNAL(clicked()), this, SLOT(sendClicked()));
	connect(ui->lineEdit, SIGNAL(returnPressed()), this, SLOT(sendClicked()));

	QTimer *mainLoop = new QTimer();
	connect(mainLoop, SIGNAL(timeout()), this, SLOT(checkMessage()));
	mainLoop->start(200);
}

MainWindow::~MainWindow()
{
	delete ui;
}

// member functions
void MainWindow::handleMessage(NGMessage *msg)
{
	unsigned char type = msg->getType();
	QString data = msg->getData(), temp;
	QStringList userList;

	switch(type)
	{
	case MSG_TYPE_NOTICE:
		printNotice(data);
		break;
	case MSG_TYPE_LIST:
		userList = data.split("|");
		if(userList.size() > 0)
		{
			for(int i = 0; i < userList.size(); i++)
				temp += userList[i] + "\n";
			ui->usersEdit->setText(temp);
		}
		break;
	case MSG_TYPE_CHAT_NORMAL:
		data = "[" + data.replace("|", "] ");
		printNormal(data);
		break;
	case MSG_TYPE_CHAT_WHISPER_TO:
		data = " to [" + data.replace("|", "] ");
		printWhisper(data);
		break;
	case MSG_TYPE_CHAT_WHISPER_FROM:
		data = " from [" + data.replace("|", "] ");
		printWhisper(data);
		break;
	}
}

void MainWindow::printNormal(QString str)
{
	chatData += str + "<br />";
	ui->chatEdit->setHtml(chatData);
}

void MainWindow::printNotice(QString str)
{
	chatData += "<b><font color='orange'>" + str + "</font></b><br />";
	ui->chatEdit->setHtml(chatData);
}

void MainWindow::printWhisper(QString str)
{
	chatData += "<font color='red'>" + str + "</font><br />";
	ui->chatEdit->setHtml(chatData);
}

// slots
void MainWindow::checkMessage()
{
	if(NGineClient::getQueueSize() > 0)
	{
		NGMessage *msg = NGineClient::getFirstMessage();
		handleMessage(msg);
	}
}

void MainWindow::sendClicked()
{
	QString messageToSend = ui->lineEdit->text();
	if(!messageToSend.compare("/quit"))
		this->close();
	else if(messageToSend.startsWith("/whisper "))
	{
		// handle whisper
		messageToSend = messageToSend.remove(0, strlen("/whisper "));
		messageToSend[messageToSend.indexOf(' ')] = '|';
		qDebug() << messageToSend;
		NGineClient::sendToServer(MSG_TYPE_CHAT_WHISPER_TO, messageToSend.toAscii());
	}
	else if(messageToSend.startsWith("/w "))
	{
		// handle whisper
		messageToSend = messageToSend.remove(0, strlen("/w "));
		messageToSend[messageToSend.indexOf(' ')] = '|';
		qDebug() << messageToSend;
		NGineClient::sendToServer(MSG_TYPE_CHAT_WHISPER_TO, messageToSend.toAscii());
	}
	else
		NGineClient::sendToServer(MSG_TYPE_CHAT_NORMAL, messageToSend.toAscii());

	ui->lineEdit->clear();
	ui->lineEdit->setFocus();
}
